package com.dh.leetcode.k1;

import org.junit.Assert;
import org.junit.Test;

/**
 * @ClassName: _1404_number_of_steps_to_reduce_a_number_in_binary_representation_to_one
 * @Description: 1404. 将二进制表示减到 1 的步骤数
 * 给你一个以二进制形式表示的数字 s 。请你返回按下述规则将其减少到 1 所需要的步骤数：
 * <p>
 * 如果当前数字为偶数，则将其除以 2 。
 * <p>
 * 如果当前数字为奇数，则将其加上 1 。
 * <p>
 * 题目保证你总是可以按上述规则将测试用例变为 1 。
 * <p>
 * <p>
 * <p>
 * 示例 1：
 * <p>
 * 输入：s = "1101"
 * 输出：6
 * 解释："1101" 表示十进制数 13 。
 * Step 1) 13 是奇数，加 1 得到 14
 * Step 2) 14 是偶数，除 2 得到 7
 * Step 3) 7  是奇数，加 1 得到 8
 * Step 4) 8  是偶数，除 2 得到 4
 * Step 5) 4  是偶数，除 2 得到 2
 * Step 6) 2  是偶数，除 2 得到 1
 * 示例 2：
 * <p>
 * 输入：s = "10"
 * 输出：1
 * 解释："10" 表示十进制数 2 。
 * Step 1) 2 是偶数，除 2 得到 1
 * 示例 3：
 * <p>
 * 输入：s = "1"
 * 输出：0
 * <p>
 * <p>
 * 提示：
 * <p>
 * 1 <= s.length <= 500
 * s 由字符 '0' 或 '1' 组成。
 * <p>
 * https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-in-binary-representation-to-one/
 * @Author: shouzimu
 * @Date: 2021/12/14 10:49
 */
public class _1404_number_of_steps_to_reduce_a_number_in_binary_representation_to_one {

    public int numSteps(String s) {
        int len = s.length();
        int num = 0;
        while (len > 1) {
            if (s.charAt(len - 1) == '1') {
                char carry = '1';
                char[] array = s.toCharArray();
                for (int i = len - 1; i >= 0; i--) {
                    if (array[i] == '1') {
                        carry = '1';
                        array[i] = '0';
                    } else {
                        array[i] = '1';
                        carry = '0';
                        break;
                    }
                }
                if (carry == '1') {
                    char[] newArray = new char[len + 1];
                    System.arraycopy(array, 0, newArray, 1, array.length);
                    newArray[0] = '1';
                    array = newArray;
                }
                s = new String(array);
            } else {
                s = s.substring(0, len - 1);
            }
            num++;
            len = s.length();
        }
        return num;
    }

    @Test
    public void numStepsTest() {
        Assert.assertEquals(6, numSteps("1101"));
        Assert.assertEquals(1, numSteps("10"));
        Assert.assertEquals(0, numSteps("1"));
    }
}
